//
//  GameboardView.swift
//  StoreMaker
//
//  Created by 展恒 on 15/12/30.
//  Copyright © 2015年 赵百川. All rights reserved.
//

import UIKit

class GameboardView: UIView {

    var dimension:Int = 0
    var tileWidth:CGFloat = 0.0
    var tilePadding:CGFloat = 0.0
    var cornerRadius:CGFloat = 0.0
    
    var tiles:Dictionary<NSIndexPath,TileView>
    
    let provider = AppearanceProvider()
    
    let tilePopStartScale:CGFloat = 0.1
    let tilePopMaxScale:CGFloat = 1.1
    let tilePopDelay:NSTimeInterval = 0.05
    let tileExpandTime:NSTimeInterval = 0.18
    let tileContractTime:NSTimeInterval = 0.08
    
    let tileMergeStartScale:CGFloat = 1.0
    let tileMergeExpandTime:NSTimeInterval = 0.08
    let tileMergeContractTime:NSTimeInterval = 0.08
    
    let perSquareSlideDuration:NSTimeInterval = 0.08
    init(dimension d:Int,tileWidth width:CGFloat,tilePadding padding:CGFloat,cornerRadius radius:CGFloat,backgroundColor:UIColor,foregroundColor:UIColor){
        assert(d > 0)
        dimension = d
        tileWidth = width
        tilePadding = padding
        cornerRadius = radius
        tiles = Dictionary()
        let sideLength = padding + CGFloat(dimension)*(width + padding)
        super.init(frame:CGRectMake(0, 0, sideLength, sideLength))
        setupBackground(backgroundColor: backgroundColor, tileColor: foregroundColor)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func reset(){
        //重置
        for(_,tile)in tiles{
            tile.removeFromSuperview()
        }
        tiles.removeAll(keepCapacity: true)
        
    }
    //返回一个给定的位置是否有效。用于边界检查。
    func positionIsValid(pos:(Int,Int)) -> Bool{
        let (x,y) = pos
        return (x >= 0 && x < dimension && y >= 0 && y < dimension)
    }
    func setupBackground(backgroundColor bgColor:UIColor,tileColor:UIColor)
    {
        backgroundColor = bgColor
        var xCursor = tilePadding
        var yCursor :CGFloat
        let bgRadius = (cornerRadius >= 2) ? cornerRadius - 2 : 0
        for _ in 0..<dimension {
            yCursor = tilePadding
            for _ in 0..<dimension{
                let background = UIView(frame: CGRectMake(xCursor, yCursor, tileWidth, tileWidth))
                background.layer.cornerRadius = bgRadius
                background.backgroundColor = tileColor
                addSubview(background)
                yCursor += tilePadding + tileWidth
            }
            xCursor += tilePadding + tileWidth
        }
    }
    //更新的棋盘,在一个给定的位置插入一个tile。tile将插入一个“pop”动画。
    func insertTile(pos: (Int,Int), value:Int)
    {
        assert(positionIsValid(pos))
        let (row, col) = pos
        let x = tilePadding + CGFloat(col)*(tileWidth + tilePadding)
        let y = tilePadding + CGFloat(row)*(tileWidth + tilePadding)
        let r = (cornerRadius >= 2) ? cornerRadius - 2 : 0
        let tile = TileView(position: CGPointMake(x, y), width: tileWidth, value: value, radius: r, delegate: provider)
        tile.layer.setAffineTransform(CGAffineTransformMakeScale(tilePopStartScale, tilePopStartScale))
        
        addSubview(tile)
        bringSubviewToFront(tile)
        tiles[NSIndexPath(forRow: row, inSection: col)] = tile
        //添加棋盘
        UIView.animateWithDuration(tileExpandTime, delay: tilePopDelay, options: UIViewAnimationOptions.TransitionNone,
            animations: {
                // Make the tile 'pop'
                tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale))
            },
            completion: { finished in
                // 缩小后的瓷砖的持久性有机污染物 Shrink the tile after it 'pops'
                UIView.animateWithDuration(self.tileContractTime, animations: { () -> Void in
                    tile.layer.setAffineTransform(CGAffineTransformIdentity)
                })
        })
        //更新的棋盘,tile从一个位置移动到另一个地方。如果此举是要崩溃
        //tile到一个新的tile,tile将“流行”后移动到新位置。
        func moveOneTile(from:(Int,Int),to:(Int,Int),value: Int){
            assert(positionIsValid(from) && positionIsValid(to))
            let (fromRow,fromCol) = from
            let (toRow,toCol) = to
            let fromKey = NSIndexPath(forRow: fromRow, inSection: fromCol)
            let toKey = NSIndexPath(forRow: toRow, inSection: toCol)
            //得到tile
            guard let tile = tiles[fromKey] else{
                assert(false,"placeholder error")
                
            }
            let endTile = tiles[toKey]
            //make the frame
            var finalFrame = tile.frame
            finalFrame.origin.x = tilePadding + CGFloat(toCol)*(tileWidth + tilePadding)
            finalFrame.origin.y = tilePadding + CGFloat(toRow)*(tileWidth + tilePadding)
            //更新棋盘
            tiles.removeValueForKey(fromKey)
            tiles[toKey] = tile
            //动画
            let shouldPop = endTile != nil
            
            UIView.animateWithDuration(perSquareSlideDuration, delay: 0.0, options: UIViewAnimationOptions.BeginFromCurrentState, animations: { () -> Void in
                tile.frame = finalFrame
                }) { (finished:Bool) -> Void in
                    tile.value = value
                    endTile?.removeFromSuperview()
                    if !shouldPop || !finished{
                        return
                    }
                    tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tileMergeStartScale, self.tileMergeStartScale))
                    //pop tile
                    UIView.animateWithDuration(self.tileMergeExpandTime, animations: { () -> Void in
                        tile.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale))
                        }, completion: { finished in
                            UIView.animateWithDuration(self.tileContractTime){
                                tile.layer.setAffineTransform(CGAffineTransformIdentity)
                            }
                    })
            }
        }
    }
    //更新的棋盘,将两个瓷砖从原来的位置移动到一个共同的目的地。这一行动总是 represents tile collapse, and the combined tile 'pops' after both tiles move into position.
    //代表瓦崩溃,合并后的瓷砖“弹出”瓷砖后进入的位置。 represents tile collapse, and the combined tile 'pops' after both tiles move into position.
    
    func moveTwoTiles(from:((Int,Int),(Int,Int)),to:(Int,Int),value:Int){
        assert(positionIsValid(from.0) && positionIsValid(from.1) && positionIsValid(to))
        let (fromRowA,fromColA) = from.0
        let (fromRowB,fromColB) = from.1
        let (toRow,toCol) = to
        let fromKeyA = NSIndexPath(forRow: fromRowA, inSection: fromColA)
        let fromKeyB = NSIndexPath(forRow: fromRowB, inSection: fromColB)
        let toKey = NSIndexPath(forRow: toRow, inSection: toCol)
        guard let tileA = tiles[fromKeyA] else{
            assert(false,"placeholder error")
        }
        guard let tileB = tiles[fromKeyB] else{
            assert(false,"placeholder error")
        }
        //大小
        var finalFrame = tileA.frame
        finalFrame.origin.x = tilePadding + CGFloat(toCol)*(tileWidth + tilePadding)
        finalFrame.origin.y = tilePadding + CGFloat(toRow)*(tileWidth + tilePadding)
        
        //更新状态
       let oldTile = tiles[toKey]
        oldTile?.removeFromSuperview()
        tiles.removeValueForKey(fromKeyA)
        tiles.removeValueForKey(fromKeyB)
        tiles[toKey] = tileA
        
        UIView.animateWithDuration(perSquareSlideDuration,
            delay: 0.0,
            options: UIViewAnimationOptions.BeginFromCurrentState,
            animations: {
                // Slide tiles
                tileA.frame = finalFrame
                tileB.frame = finalFrame
            },
            completion: { finished in
                tileA.value = value
                tileB.removeFromSuperview()
                if !finished {
                    return
                }
                tileA.layer.setAffineTransform(CGAffineTransformMakeScale(self.tileMergeStartScale, self.tileMergeStartScale))
                // Pop tile
                UIView.animateWithDuration(self.tileMergeExpandTime,
                    animations: {
                        tileA.layer.setAffineTransform(CGAffineTransformMakeScale(self.tilePopMaxScale, self.tilePopMaxScale))
                    },
                    completion: { finished in
                        // Contract tile to original size
                        UIView.animateWithDuration(self.tileMergeContractTime) {
                            tileA.layer.setAffineTransform(CGAffineTransformIdentity)
                        }
                })
        })
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
}
